import javax.swing.*;
import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.CharBuffer;


public class SocketClinet {
    private final static String SOAP_BEGIN = "<SOAP>";
    private final static String SOAP_END = "</SOAP>";
    private String host;
    private Integer port;
    private static GameGUI gameGUI;
    private String sendMsg = null;
    private volatile Integer flag = 0; //是否有新消息到来 volatile 可以再不同线程之间共享
    StrategyFactory strategyFactory = new StrategyFactory();
    private String receive = "";
    Message message = new Message();


    public String getReceive() {
        return receive;
    }

    public void setSendMsg(String sendMsg) {
        this.flag = 1;
        message.setType(gameGUI.getChessType());
        message.setEventName("msg");
        message.setContent(sendMsg);
    }

    public SocketClinet(String host, Integer port, GameGUI gameGUI1) {
        this.host = host;
        this.port = port;
        gameGUI = gameGUI1;
    }

    public void addListener(String eventName, EventApi eventApi) {
        strategyFactory.strategyMaps.put(eventName, eventApi);
    }

    // 发送消息线程
    class SendThread extends Thread {
        private Socket socket;

        public SendThread(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            while (true) {
                try {
                    String content = message.getContent();
                    // 有发送消息时就发送
                    if (flag == 1 && null != content) {
                        PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
                        pw.write(SOAP_BEGIN + content + SOAP_END);
                        pw.flush();
                        message.setContent(null);
                        flag = 0;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    // 接受消息线程
    class ReceiveThread extends Thread {
        private Socket socket;

        public ReceiveThread(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            while (true) {
                try {
                    Reader reader = new InputStreamReader(socket.getInputStream(), "GBK");
                    CharBuffer charBuffer = CharBuffer.allocate(8192);
                    int index = -1;
                    String temp = "";
                    while ((index = reader.read(charBuffer)) != -1) {
                        charBuffer.flip();
                        temp += charBuffer.toString();
                        if (temp.indexOf(SOAP_END) != -1 && temp.indexOf(SOAP_BEGIN) != -1) {
                            String s = temp.replaceAll(SOAP_BEGIN, "");
                            s = s.replaceAll(SOAP_END, "");
                            receive = s;
                            Message message = ArrayUtils.jsonToMessage(s);
                            strategyFactory.getApiByFuncName(message.getEventName()).doEvent(message);
                            temp = "";
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    System.exit(0);

                }
            }
        }
    }

    public void start() throws UnknownHostException, IOException {
        Socket socket = new Socket(host, port);
        System.out.println(String.format("客户端启动 主机：%s 端口：%d", host, port));
        addListener("gameOver", new EventApi() {
            @Override
            public void doEvent(Message message) {
                gameGUI.jButtons.get(2).setEnabled(false); // 认输不可用
                // 准备可用
                gameGUI.resetRead();
                Integer type = message.getType();
                gameGUI.getjLabel()[0].setText(type == gameGUI.getChessType()?"你赢了":"你输了");

//                JOptionPane.showMessageDialog(null,
//                        type == gameGUI.getChessType()?"你赢了":"你输了",
//                        type == gameGUI.getChessType()?"恭喜":"",
//                        JOptionPane.DEFAULT_OPTION);
            }
        });
        addListener("giveup", new EventApi() {
            @Override
            public void doEvent(Message message) {
                gameGUI.jButtons.get(2).setEnabled(false); // 认输不可用
                // 准备可用
                gameGUI.resetRead();
                gameGUI.getjLabel()[0].setText("你赢了");

//                JOptionPane.showMessageDialog(null,
//                        "你赢了",
//                        "恭喜",
//                        JOptionPane.DEFAULT_OPTION);
            }
        });
        addListener("msg", new EventApi() {
            @Override
            public void doEvent(Message message) {
                JLabel jLabel = gameGUI.getjLabel()[0];
                Integer type = message.getType();
                if (type == 1) {// 黑棋发来的消息
                    jLabel.setText("现在是白棋下");
                } else if (type == 2) {
                    jLabel.setText("现在是黑棋下");
                }
                String content = message.getContent();
                gameGUI.getChess().Edge = ArrayUtils.JSON2Array(content);
                gameGUI.repaint();
                gameGUI.setChessFlag(true);
            }
        });
        // 开始
        addListener("reGame", new EventApi() {
            @Override
            public void doEvent(Message message) {
                JLabel jLabel = gameGUI.getjLabel()[0];
                Integer type = Integer.valueOf(message.getContent());
                gameGUI.setType(type);
                if (type == 1) {// 黑棋先行
                    gameGUI.setChessFlag(true);
                    jLabel.setText("现在是黑棋下");
                    gameGUI.getjLabel()[1].setText("你是黑棋");
                } else if (type == 2) {
                    jLabel.setText("现在是黑棋下");
                    gameGUI.getjLabel()[1].setText("你是白棋");
                }
                gameGUI.getChess().reset();
                gameGUI.repaint();
                gameGUI.setStart(true);
                gameGUI.jButtons.get(2).setEnabled(true);
                gameGUI.jButtons.get(3).setEnabled(false);
                gameGUI.jButtons.get(4).setEnabled(false);
            }
        });
        addListener("reading", new EventApi() {
            @Override
            public void doEvent(Message message) {
                JButton jButton = gameGUI.jButtons.get(3);
                jButton.setVisible(true);
                gameGUI.setReady(true);
                gameGUI.jButtons.get(3).setEnabled(true);
            }
        });
        new SendThread(socket).start();
        new ReceiveThread(socket).start();
        JButton createBtn = gameGUI.jButtons.get(1);
        createBtn.setEnabled(false);
        createBtn.setText("连接成功");
    }

    public static void main(String[] args) throws UnknownHostException, IOException {
        new SocketClinet("127.0.0.1", 8081, gameGUI).start();
    }


}

